using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace ScreenToGif.Windows.Other;

public partial class ErrorDialog
{
    public Exception Exception { get; set; }

    public ErrorDialog()
    {
        InitializeComponent();
    }

    #region Methods

    private Brush GetIcon(Icons icon)
    {
        switch (icon)
        {
            case Icons.Error:
                return (Brush)FindResource("Vector.Cancel.Round");
            case Icons.Info:
                return (Brush)FindResource("Vector.Info");
            case Icons.Success:
                return (Brush)FindResource("Vector.Ok.Round");
            case Icons.Warning:
                return (Brush)FindResource("Vector.Warning");
            case Icons.Question:
                return (Brush)FindResource("Vector.Question");

            default:
                return (Brush)FindResource("Vector.Info");
        }
    }

    private void PrepareOk(string title, string instruction, string observation, Icons icon)
    {
        CancelButton.Visibility = Visibility.Collapsed;
        YesButton.Visibility = Visibility.Collapsed;
        NoButton.Visibility = Visibility.Collapsed;
        DetailsButton.Visibility = Exception != null ? Visibility.Visible : Visibility.Collapsed;

        OkButton.Focus();

        IconBorder.Background = GetIcon(icon);
        InstructionLabel.Content = instruction;
        DetailsRun.Text = observation;
        Title = title;
    }

    private void PrepareOkCancel(string title, string instruction, string observation, Icons icon)
    {
        YesButton.Visibility = Visibility.Collapsed;
        NoButton.Visibility = Visibility.Collapsed;
        DetailsButton.Visibility = Exception != null ? Visibility.Visible : Visibility.Collapsed;

        CancelButton.Focus();

        IconBorder.Background = GetIcon(icon);
        InstructionLabel.Content = instruction;
        DetailsRun.Text = observation;
        Title = title;
    }

    private void PrepareAsk(string title, string instruction, string observation, Icons icon)
    {
        CancelButton.Visibility = Visibility.Collapsed;
        OkButton.Visibility = Visibility.Collapsed;
        DetailsButton.Visibility = Exception != null ? Visibility.Visible : Visibility.Collapsed;

        NoButton.Focus();

        IconBorder.Background = GetIcon(icon);
        InstructionLabel.Content = instruction;
        DetailsRun.Text = observation;
        Title = title;
    }

    /// <summary>
    /// Shows a Ok dialog.
    /// </summary>
    /// <param name="title">The title of the window.</param>
    /// <param name="instruction">The main instruction.</param>
    /// <param name="observation">A complementar observation.</param>
    /// <param name="exception">The exception of the error.</param>
    /// <param name="icon">The image of the dialog.</param>
    /// <returns>True if Ok</returns>
    public static bool Ok(string title, string instruction, string observation, Exception exception, Icons icon = Icons.Error)
    {
        var dialog = new ErrorDialog { Exception = exception };
        dialog.PrepareOk(title, instruction, observation.Replace(@"\n", Environment.NewLine).Replace(@"\r", ""), icon);
        var result = dialog.ShowDialog();

        return result.HasValue && result.Value;
    }

    /// <summary>
    /// Shows a Ok/Cancel dialog.
    /// </summary>
    /// <param name="title">The title of the window.</param>
    /// <param name="instruction">The main instruction.</param>
    /// <param name="observation">A complementar observation.</param>
    /// <param name="exception">The exception of the error.</param>
    /// <param name="icon">The image of the dialog.</param>
    /// <returns>True if Ok</returns>
    public static bool OkCancel(string title, string instruction, string observation, Exception exception, Icons icon = Icons.Error)
    {
        var dialog = new ErrorDialog { Exception = exception };
        dialog.PrepareOkCancel(title, instruction, observation.Replace(@"\n", Environment.NewLine).Replace(@"\r", ""), icon);
        var result = dialog.ShowDialog();

        return result.HasValue && result.Value;
    }

    /// <summary>
    /// Shows a Yes/No dialog.
    /// </summary>
    /// <param name="title">The title of the window.</param>
    /// <param name="instruction">The main instruction.</param>
    /// <param name="observation">A complementar observation.</param>
    /// <param name="exception">The exception of the error.</param>
    /// <param name="icon">The image of the dialog.</param>
    /// <returns>True if Yes</returns>
    public static bool Ask(string title, string instruction, string observation, Exception exception, Icons icon = Icons.Question)
    {
        var dialog = new ErrorDialog { Exception = exception };
        dialog.PrepareAsk(title, instruction, observation.Replace(@"\n", Environment.NewLine).Replace(@"\r", ""), icon);
        var result = dialog.ShowDialog();

        return result.HasValue && result.Value;
    }

    #endregion

    #region Events

    private void FalseActionButton_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = false;
    }

    private void TrueActionButton_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
    }

    private void DetailsButton_Click(object sender, RoutedEventArgs e)
    {
        if (Exception == null)
            return;

        var viewer = new ExceptionViewer(Exception);
        viewer.ShowDialog();
    }

    private async void SendButton_Click(object sender, RoutedEventArgs e)
    {
        var feedback = new Feedback { Topmost = true };

        if (feedback.ShowDialog() != true)
            return;

        if (App.MainViewModel != null)
            await Task.Factory.StartNew(App.MainViewModel.SendFeedback, TaskCreationOptions.LongRunning);
    }

    #endregion

    /// <summary>
    /// Dialog Icons.
    /// </summary>
    public enum Icons
    {
        /// <summary>
        /// Information. Blue.
        /// </summary>
        Info,

        /// <summary>
        /// Warning, yellow.
        /// </summary>
        Warning,

        /// <summary>
        /// Error, red.
        /// </summary>
        Error,

        /// <summary>
        /// Success, green.
        /// </summary>
        Success,

        /// <summary>
        /// A question mark, blue.
        /// </summary>
        Question,
    }
}